package com.evildog.workspace.auth.grant;


import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.evildog.workspace.auth.enums.AuthCustomExceptionDesc;
import com.evildog.workspace.common.exception.BadRequestException;
import com.evildog.workspace.common.result.Result;
import com.evildog.workspace.security.jwt.constant.TokenConstant;
import com.evildog.workspace.security.jwt.core.TokenUserInfo;
import com.evildog.workspace.security.jwt.util.JwtUtil;
import com.evildog.workspace.system.api.feign.UserClient;
import com.evildog.workspace.system.api.vo.UserVO;
import io.jsonwebtoken.Claims;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * RefreshTokenGranter
 */
@Component(RefreshTokenGranter.GRANT_TYPE)
@AllArgsConstructor
public class RefreshTokenGranter implements Granter {

    private final UserClient userClient;
    private final JwtUtil jwtUtil;

    public static final String GRANT_TYPE = "refresh_token";

    @Override
    public TokenUserInfo grant(GrantParameter tokenParameter) {
        TokenUserInfo tokenUserInfo = null;
        String refreshToken = tokenParameter.getRefreshToken();

        if (StrUtil.isNotBlank(refreshToken)) {
            Claims claims = jwtUtil.parseJWT(refreshToken);
            if (claims == null) {
                throw new BadRequestException(AuthCustomExceptionDesc.REFRESH_TOKEN_EXPIRED);
            }

            String tokenType = StrUtil.toString(claims.get(TokenConstant.TOKEN_TYPE));
            Long userId = NumberUtil.parseLong(String.valueOf(claims.get(TokenConstant.USER_ID)));

            if (tokenType.equals(TokenConstant.REFRESH_TOKEN)) {

                Result<UserVO> userVOResult = userClient.getUser(userId);
                if (userVOResult.isSuccess()) {
                    UserVO userVO = userVOResult.getData();
                    tokenUserInfo = new TokenUserInfo();
                    tokenUserInfo.setAvatar(userVO.getAvatar())
                            .setNickname(userVO.getNickname())
                            .setUserId(userVO.getId());
                }
            }
        }


        return tokenUserInfo;
    }
}
